;(function(S) {
	var widgetIncCache = {};
	/**
	 * 组件基类，用于创建带有UI性质的组件，继承自该基类的组件都有从创建到销毁都有完整的生命周期
	 * 并且附加plugin机制
	 *     S.declare('Animal',S.Widget,{
	 *         init:function(){
	 *             console.log('init');
	 *         }
	 *     });
	 *
	 * @class S.Widget
	 * @extends S.Attribute
	 */
	S.declare('Widget', S.Attribute, {
		/**
		 * 为container添加的Id,该Id也为实例化后可以根据此ID获取实例对象
		 * 如果没有指定，则会自动生成一个Id，格式为widget-uuid
		 * @property id
		 * @default ''
		 */
		id : '',
		/**
		 * 触发该widget操作的node
		 * @property node
		 * @default null
		 */
		node : null,
		/**
		 * ui渲染的位置
		 * @property container
		 * @default ''
		 */
		container : '',
		/**
		 * 为container添加的类
		 * @property className
		 * @default 'ui-base'
		 */
		className : 'simple-base',
		/**
		 * 实例化时需要执行的插件
		 * @property {Array} plugins
		 * @default []
		 */
		plugins : [],
		/**
		 * 存储实例化的插件实例对象,可以通过插件的名字获取
		 * @property {Object} pluginsInc
		 * @default {}
		 */
		pluginsInc : {},
		/**
		 * 初始化init，在初始化的过程中首先获取需要绑定事件的node，渲染UI的位置
		 * @method init
		 */

		position : null,

		init : function() {
            
            this.node = this.get('node');
			this.container = this.get('container');
			
			widgetIncCache[this.id] = this;
		},
		/**
		 * 初始化之后，执行的一些操作，实例化配置的插件，并且触发afterInit事件
		 * @method preamble
		 */
		afterInit : function() {
            this.render();
			/*插件机制*/
			if (this.plugins.length) {
				S.each(this.plugins, function(name, index) {
					if (this.constructor.plugins[name]) {
						this.pluginsInc[name] = new this.constructor.plugins[name]({
							host : this
						});
					}
				}, this);
			}
			this.trigger('afterInit');
		},
		/**
		 * 获取node节点
		 * @method getNode
		 * @param {Object} node
		 */
		getterNode : function(node) {
			if (node) {
				return $(node);
			}
			//else {
			//S.error('S.Widget: ' + ' 请指定一个node节点！');
			//}
		},
		/**
		 * 获取container节点
		 * @method getContainer
		 * @param {Object} container
		 */
		getterContainer : function(container) {
			if (container) {
				return $(container).attr('id', this.get('id')).addClass(this.get('className'));
			} else {
				return $('<div id=' + this.get('id') + ' class="' + this.get('className') + '"></div>').appendTo(document.body);
			}
		},
		getterId : function(id) {
			if (id) {
				return id;
			}
			return 'widget-' + (S.uuid++);
		},
		/**
		 * 渲染操作，其中会执行renderUI与bindUI两个方法，分别触发beforeRender
		 * @method render
		 * @param {Object} container
		 */
		render : function() {
			if (this.trigger('beforeRender') === false) {
				return false;
			}
			this.renderUI();
			if (this.trigger('afterRender') === false) {
				return false;
			}
			this.setPosition(this.position);
			if (this.trigger('beforeBind') === false) {
				return false;
			}
			this.bindUI();
			if (this.trigger('afterBind') === false) {
				return false;
			}
		},
		renderUI : $.noop,
		bindUI : $.noop,
		show : function() {
			this.set('visible', true);
		},
		hide : function() {
			this.set('visible', false);
		},
		setVisible : function(isVisible) {
			if (isVisible) {
				this.container.css('display', '');
			} else {
				this.container.css('display', 'none');
			}
			return isVisible;
		},
		setPosition : function(position) {
			if (position) {
				if ( typeof position == "string") {
					S.position.at({
						node : this.node,
						referNode : this.referNode,
						points : position
					});
				} else {
					this.node.css({
						top : position[1],
						left : position[0]
					});
				}
			} else {
				S.position.atBody(this.node);
			}
		},
		destroy : function() {
			if (this.trigger('beforeDestory') === false) {
				return false;
			}
			this.node = null;
			//是自动生成的container
			if (/widget/.test(this.get('id'))) {
				this.container.remove();
			} else {
				this.container.empty();
			}
			this.container = null;
			this.off();
			//this.unplug();
			if (this.pluginInc) {
				S.each(this.pluginInc, function(cacheInc) {
					cacheInc.destroy && cacheInc.destroy();
				});
			}
			this.trigger('afterDestory');
		}
	});

	S.Widget.byId = function(id) {

		if (widgetIncCache[id]) {
			return widgetInCache[id];
		}
		return null;
	}
})(Simple);
